package gestionCandidats;

import modele.Bd;
import modele.Parcours;

import serveur.Serveur;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.healthmarketscience.rmiio.GZIPRemoteInputStream;
import com.healthmarketscience.rmiio.RemoteInputStreamClient;
import com.healthmarketscience.rmiio.RemoteInputStreamServer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.rmi.Naming;
import java.util.SortedSet;

public class GestionCandidats extends JPanel implements ActionListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = 4L;
	static final Color colorInfo = Color.orange;
	static final Color colorModif = Color.green;

	// La fenetre principale
	private JFrame frame                = null;
	// Diverses fenetres
	private JPanel etudiantAffiche     = null;
	private JPanel evaluationAffiche     = null;
	private JPanel parcoursAffiche     = null;
	private JPanel uniteEnseignementAffiche     = null;
	private JPanel uniteEnseignementMaj = null;;
	private JPanel dossierAffiche     = null;
	private JPanel dossierRetenuAffiche     = null;
	private JPanel demandeAffiche     = null;
	//private JWindow dossierVeto     = null;
	//private JWindow dossierProposition     = null;
	private JFrame ficheAffiche     = null;
//	private JFrame dossierPropoUes     = null;

	// La barre de menus
	private JMenuBar menuBar            = null;
	private JMenuItem save=null;
	private JMenuItem importApoflux=null;
	private JMenuItem quitter=null;
	private JMenuItem parcourspdf=null, parcourssynthesepdf=null, UEsdetails=null, UEssynthese=null;
	private JMenuItem stat=null, demandes=null, evaluations=null, propositions=null;
	private JMenuItem help=null;
	
	// Cette application joue le role du client
	private Serveur serveur;
	private String host, port;
	private Bd bd;

	public GestionCandidats(String[] argv){
		if (argv.length==2) {
			host=argv[0]; 
			port=argv[1];
		}
		else if (argv.length==1) {
			host=argv[0]; 
			port=null;
		}
		 else {
			host=null;
			port=null;
		 }
		
		frame = new JFrame("Gestion des candidats Master");
		
		//connexion au serveur
		if (host==null)
			host = JOptionPane.showInputDialog("Nom du serveur","lepiote");

		if (port==null)
			port = JOptionPane.showInputDialog("Numero du port","5000");
		try {
			serveur = (Serveur)Naming.lookup("rmi://" + host+":"+port+"/Master");
			bd = serveur.getBd();
			serveur.AddClient();
		}
		catch(Exception e){
			JOptionPane.showMessageDialog(this,"Connexion impossible.\n\n"+"Le service est actuellement interrompu","Attention",JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}
		
		setLayout(new BorderLayout());

		JPanel top = new JPanel();
		top.setLayout(new BorderLayout());
		add(top, BorderLayout.NORTH);
		createMenus();
		top.add(menuBar, BorderLayout.NORTH);
		
		// put Appli in a frame and show it
		frame.getContentPane().add(this, BorderLayout.CENTER);
		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent winEvt) {
				Quit();
			}
		} );

		frame.pack();
		
		  // make the frame half the height and width
	    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	    int height = screenSize.height;
	    int width = screenSize.width;
	    frame.setSize(width/2, height/2);

		 // center the jframe on screen
	    frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	public JFrame  getFrame()                   {return frame;}
	public JPanel  getParcoursAffiche()         {return parcoursAffiche;}
	public JPanel getUniteEnseignementAffiche() {return uniteEnseignementAffiche;}
	public JPanel getUniteEnseignementMaj() {return uniteEnseignementMaj;}
	public JPanel getEtudiantAffiche()         {return etudiantAffiche;}
	public JPanel getEvaluationAffiche()         {return evaluationAffiche;}
	public JFrame  getFicheAffiche()            {return ficheAffiche;}
	public JPanel getDossierAffiche()          {return dossierAffiche;}
	public JPanel getDossierRetenuAffiche()    {return dossierRetenuAffiche;}
	public JPanel getDemandeAffiche()          {return demandeAffiche;}

	public Bd      getBd() throws Exception     {return serveur.getBd();}

	private void Quit() {
		SauvegarderBd();
		try {
			serveur.RemoveClient();
		} catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, e.getMessage(),"Erreur : Attention",JOptionPane.ERROR_MESSAGE);
		}
		System.exit(0);
	}

	private void SauvegarderBd() {
		int res = JOptionPane.showConfirmDialog(this,"Voulez-vous sauvegarder les données actuelles ?","Sauvegarde de la base",JOptionPane.YES_NO_CANCEL_OPTION);
		if (res == JOptionPane.YES_OPTION) {
			try {
				bd.Sauvegarde();
			} catch (Exception e) {
				e.printStackTrace();
				JOptionPane.showMessageDialog(this, e.getMessage(),"Sauvegarde IMPOSSIBLE : Attention",JOptionPane.ERROR_MESSAGE);
			}
		}
	}
	
	private void ImportApoflux() {
		String filename="";
		JFileChooser c = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("CSV files", "csv");
		c.setFileFilter(filter);
		if (JFileChooser.APPROVE_OPTION == c.showOpenDialog(this))
			filename = c.getSelectedFile().getPath();
		else
			return;

		if (JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(this,"Les données nouvelles d'Apoflux vont être ajoutées à la base","Importation : Attention", JOptionPane.OK_CANCEL_OPTION)) {
			RemoteInputStreamServer istream = null;
			try {
				istream = new GZIPRemoteInputStream(new BufferedInputStream(
						new FileInputStream(filename)));
				// call server (note export() call to get actual remote interface)
				int num = bd.importeListeApoflux(istream.export());
				JOptionPane.showMessageDialog(this, num+" nouveaux dossiers importés", "Importation",JOptionPane.INFORMATION_MESSAGE);

			} 
			catch(Exception ex){
				JOptionPane.showMessageDialog(this, ex.getMessage(),"Importation Apoflux IMPOSSIBLE : Attention",JOptionPane.ERROR_MESSAGE);
				ex.printStackTrace();
			}
			finally {
				// since the server should have consumed the stream in the sendFile()
				// call, we always want to close the stream
				if(istream != null) istream.close();
			}
		}
	}

	/**
	 * Create menus
	 */
	public void createMenus() {
		// ***** create the menubar ****
		menuBar = new JMenuBar();
		//final GestionCandidats gc = this;
		///////////////////////
		JMenu adminMenu = menuBar.add(new JMenu("Gestion Base"));
		save = addMenuItem(adminMenu, "Sauvegarder", this);
		importApoflux = addMenuItem(adminMenu, "Importer Apoflux", this);
		adminMenu.addSeparator();
		quitter = addMenuItem(adminMenu, "Quitter", this);
		/////////////////////////////
		JMenu bdMenu = menuBar.add(new JMenu("BD Master"));
		addMenuItem(bdMenu, "liste parcours", new ParcoursAfficheAction(this));
		addMenuItem(bdMenu, "liste UE", new UniteEnseignementAfficheAction(this));
		///////////////////
		JMenu resultatMenu = menuBar.add(new JMenu("BD candidats"));
		addMenuItem(resultatMenu, "Les dossiers", new DossierAfficheAction(this));
		addMenuItem(resultatMenu, "Les retenus",new DossierRetenuAfficheAction(this));
		
		JMenu pdfMenu = menuBar.add(new JMenu("Impression"));
		parcourspdf = addMenuItem(pdfMenu, "Parcours", this);
		parcourssynthesepdf = addMenuItem(pdfMenu, "Parcours (Synthèse)", this);
		UEsdetails = addMenuItem(pdfMenu, "UEs (détails)", this);
		UEssynthese = addMenuItem(pdfMenu, "UEs (synthèse)", this);
		stat = addMenuItem(pdfMenu, "Statistiques", this);
		demandes = addMenuItem(pdfMenu, "Demandes", this);
		JMenu evalMenu = new JMenu("Evaluations");
		pdfMenu.add(evalMenu);
		evaluations = addMenuItem(evalMenu, "Toutes les évaluations", this);
		try {
			SortedSet<Parcours> parcours = bd.getParcours();
			for(Parcours p : parcours) {
				addMenuItem(evalMenu, p.getIntitule(), this);
			}
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(),"Récupération des parcours impossible : Attention",JOptionPane.ERROR_MESSAGE);
			e.printStackTrace();
		}
		propositions = addMenuItem(pdfMenu, "Propositions", this);
		
		JMenu aideMenu = menuBar.add(new JMenu("Aide"));
		help = addMenuItem(aideMenu, "A propos de l'évaluation", this);
	}
		
	private void getPdf(Bd.Documents doc) throws Exception {
		getDoc(bd.imprimer(doc));		
	}
	
	private void getEvalParcours(Parcours p) throws Exception {
		getDoc(bd.imprimerEvalParcours(p));
	}

	private void getDoc(String filename) throws Exception {
		//transfert du fichier depuis le serveur
		InputStream iStream = RemoteInputStreamClient.wrap(bd.getFile(filename));
		//choix du nom du fichier sur le client
		String pdf="";
		JFileChooser c = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("PDF files", "pdf");
		c.setFileFilter(filter);
		if (JFileChooser.APPROVE_OPTION == c.showSaveDialog(this))
			pdf = c.getSelectedFile().getPath();
		else
			return;
		//sauvegarde du fichier sur le client
		Files.copy(iStream, FileSystems.getDefault().getPath(pdf), REPLACE_EXISTING);
	}
	
//////////////////////
	private JMenuItem addMenuItem(JMenu menu, String label, ActionListener l) {
		JMenuItem item = new JMenuItem(label);
		item.addActionListener(l);
		menu.add(item);
		return item;
	}

	public static void main(String[] argv){
		new GestionCandidats(argv);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		JMenuItem source = (JMenuItem)(e.getSource());
		String name = e.getActionCommand();
		if(source==save)
			SauvegarderBd();
		if(source==importApoflux)
			ImportApoflux();
		if(source==quitter) {

			Quit();
		}
		try {
			if(source==parcourspdf)
				getPdf(Bd.Documents.PARCOURS);
			if(source==parcourssynthesepdf)
				getPdf(Bd.Documents.PARCOURS_SYNTHESE);
			if(source==UEsdetails)
				getPdf(Bd.Documents.UEs_DETAILS);
			if(source==UEssynthese)
				getPdf(Bd.Documents.UEs_SYNTHESE);
			if(source==stat)
				getPdf(Bd.Documents.STATISTIQUES);
			if(source==demandes)
				getPdf(Bd.Documents.DEMANDES);
			if(source==evaluations)
				getPdf(Bd.Documents.EVALUATIONS);
			if(source==propositions)
				getPdf(Bd.Documents.PROPOSITIONS);
			SortedSet<Parcours> parcours = bd.getParcours();
			for(Parcours p : parcours) { 
				if(name.contentEquals(p.getIntitule()))
					getEvalParcours(p);
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
			JOptionPane.showMessageDialog(this,ex.getMessage(),"Impossible d'obtenir le pdf : ",JOptionPane.ERROR_MESSAGE);
		}
		if(source==help) {
			JOptionPane.showMessageDialog(this,"<html>"+
					"Methode conseillée pour remplir la fiche d'evaluation :"+
					"<ol>"+
					" <li>Allez dans le menu <em>BD candidats</em>,<br>puis dans le menu <em>Les dossiers</em>,<br>puis apres selection d'un dossier, appuyez sur le bouton <em>Evaluation</em>.</li>"+
					" <li>Remplissez les champs (si ce n'est pas deja fait) :"+
					"  <ul>"+
					"   <li>Bac+4 acquis (en cas de doute mettre oui)</li>"+
					"   <li>moyenne Bac+3</li>"+
					"   <li>nombre d'annees pour obtenir Bac+3</li>"+
					"   <li>moyenne Bac+4</li>"+
					"   <li>nombre d'annees pour obtenir Bac+4</li>"+
					"  </ul>"+
					" cela modifie la cellule <em>note proposee</em> suivant la formule"+
					"  <ol>"+
					"   <li>Moyenne : note = (3*(Bac+4)+(Bac+3))/4</li>"+
					"   <li>Redoublement : note -= (nbBac+4 + nbBac+3 -2)/2</li>"+
					"   <li>Origine : note -= 2 si diplome etranger</li>"+
					"   <li>Cursus : note -= 2 si MIAGe, info indus ... note -= 4 si Autre</li>"+
					"  </ol>"+
					" </li>"+
					" <li>Evaluez le dossier :"+
					"  <ul>"+
					"   <li>Mettez une note entre 0 et 20 dans la case <em>note dossier</em> (assez proche de la <em>note proposee</em>!).<br>Cette note determine l'ordre global des dossiers, et aucune note est eliminatoire.<br>Ne laissez pas 0, cela indiquera visuellement que le dossier a ete evalue.</li>"+
					"   <li>Si vous pensez que le candidat n'est pas digne du Master Informatique,<br>decochez la case <em>OK pedagogique</em>, il recevra une lettre de refus.<br>Tous les autres recevront un courrier avec une proposition et/ou leurs positions dans les listes d'attentes.</li>"+
					"   <li>Si vous pensez que le candidat n'est pas digne d'un parcours du Master Informatique,<br>cochez le parcours correspondant dans la liste des <em>Parcours interdits</em>,<br>et transmettez le dossier au responsable suivant dans l'ordre des parcours demandes.</li>"+
					"   <li>Si le candidat est un redoublant,<br>listez les unites d'enseignement acquises dans la liste des <em>UEs acquises</em>.</li>"+
					"  </ul>"+
					" </li>"+
					"</ol>"+
					"</html>","Aide", JOptionPane.INFORMATION_MESSAGE);
		}
	}
}
